using System;
using System.Collections.Generic;
using System.Text;
using System.Configuration;
using System.Data.SqlClient;


namespace SqlTools.DataAccessLibrary
{
	public abstract class DbBase<PK, OBJ>
		where PK : PrimaryKey, new()
		where OBJ : BusinessObject
	{
		protected string _connectionString;
		protected string _connectionStringName;

		protected static Dictionary<PK, OBJ> _cache = null;

		static DbBase()
		{
			IEqualityComparer<PK> comparer = new PrimaryKeyEqualityComparer<PK>();
			_cache = new Dictionary<PK, OBJ>(comparer);
		
		}

		public DbBase(string connName)
		{
			_connectionStringName = connName;
			LoadConnectionString(connName);
		}

		protected void LoadConnectionString(string connName)
		{
			if ( ConfigurationManager.ConnectionStrings[connName] != null )
			{
				_connectionString = ConfigurationManager.ConnectionStrings[connName].ConnectionString;
			}
		}

		public string ConnectionStringName
		{
			get { return _connectionStringName; }
		}

		public string ConnectionString
		{
			get { return _connectionString; }
		}
     
		#region Select
		public abstract OBJ SelectByPK(PK key);
		#endregion

		#region Insert
		public virtual PK Insert(OBJ obj)
		{
			return Insert(obj, null);
		}

		public virtual PK Insert(OBJ obj, SqlConnection conn)
		{
			return Insert(obj, conn, null);
		}

		public abstract PK Insert(OBJ obj, SqlConnection conn, SqlTransaction trans);

		public virtual void Insert(DbList<OBJ> objs)
		{
			Insert(objs, null);
		}

		public virtual void Insert(DbList<OBJ> objs, SqlConnection conn)
		{
			Insert(objs, conn, null);
		}

		public virtual void Insert(DbList<OBJ> objs, SqlConnection conn, SqlTransaction trans)
		{
			foreach ( OBJ obj in objs )
			{
				Insert(obj, conn, trans);
			}
		}
		#endregion

		#region Update
		public int Update(OBJ obj)
		{
			return Update(obj, null);
		}

		public int Update(OBJ obj, SqlConnection conn)
		{
			return Update(obj, conn, null);
		}

		public abstract int Update(OBJ obj, SqlConnection conn, SqlTransaction trans);

		public int Update(DbList<OBJ> objs)
		{
			return Update(objs, null);
		}

		public int Update(DbList<OBJ> objs, SqlConnection conn)
		{
			return Update(objs, conn, null);
		}

		public int Update(DbList<OBJ> objs, SqlConnection conn, SqlTransaction trans)
		{
			int totalRows = 0;

			foreach ( OBJ obj in objs )
			{
				totalRows += Update(obj, conn, trans);
			}

			return totalRows;
		}
		#endregion

		#region Delete
		public int Delete(OBJ obj)
		{
			return Delete(obj, null);
		}

		public int Delete(OBJ obj, SqlConnection conn)
		{
			return Delete(obj, conn, null);
		}

		public abstract int Delete(OBJ obj, SqlConnection conn, SqlTransaction trans);

		public int Delete(DbList<OBJ> objs)
		{
			return Delete(objs, null);
		}

		public int Delete(DbList<OBJ> objs, SqlConnection conn)
		{
			return Delete(objs, conn, null);
		}

		public int Delete(DbList<OBJ> objs, SqlConnection conn, SqlTransaction trans)
		{
			int totalRows = 0;

			foreach ( OBJ obj in objs )
			{
				totalRows += Delete(obj, conn, trans);
			}

			return totalRows;
		}
		#endregion
	}
}
